/**
 * OSS 存储适配器
 * 简化版本，专注于图床功能
 */

import { BaseStorageAdapter } from './BaseStorageAdapter';
import { IStorageConfig, IUploadOptions, IUploadResult } from './interfaces';

/**
 * OSS 存储适配器实现
 */
export class OSSStorageAdapter extends BaseStorageAdapter {
  private ossClient: any = null;
  private bucket: string = '';
  private region: string = '';
  private endpoint: string = '';

  constructor(config: IStorageConfig = {}) {
    super('OSSStorage', config);
  }

  async initialize(config?: IStorageConfig): Promise<void> {
    const ossConfig = config?.oss || this.config.oss;
    
    if (!ossConfig) {
      throw new Error('OSS configuration is required');
    }

    this.bucket = ossConfig.bucket;
    this.region = ossConfig.region;
    this.endpoint = ossConfig.endpoint || `https://oss-${ossConfig.region}.aliyuncs.com`;

    try {
      // 动态导入 OSS SDK（避免在浏览器环境中加载）
      const OSS = await this.loadOSSSDK();
      
      this.ossClient = new OSS({
        accessKeyId: ossConfig.accessKeyId,
        accessKeySecret: ossConfig.accessKeySecret,
        bucket: this.bucket,
        region: this.region,
        endpoint: this.endpoint
      });

      // 测试连接
      await this.testConnection();
      
      this.markAsInitialized();
      this.logger.info('OSS storage adapter initialized', {
        bucket: this.bucket,
        region: this.region
      });
    } catch (error) {
      this.logger.error('Failed to initialize OSS storage', error as Error);
      throw new Error(`Failed to initialize OSS storage: ${(error as Error).message}`);
    }
  }

  async upload(file: File | Blob | Buffer, options: IUploadOptions = {}): Promise<IUploadResult> {
    this.ensureInitialized();

    const id = this.generateFileId(options.filename);
    const filename = options.filename || 'file';
    const size = this.getFileSize(file);
    const mimeType = this.getMimeType(file);
    const uploadedAt = new Date();

    try {
      // 获取图片尺寸
      let dimensions: { width: number; height: number } | undefined;
      if (file instanceof File || file instanceof Blob) {
        dimensions = await this.getImageDimensions(file);
      }

      // 上传到 OSS
      await this.ossClient.put(id, file, {
        headers: {
          'Content-Type': mimeType,
          'Cache-Control': 'public, max-age=31536000'
        },
        meta: {
          originalName: filename,
          uploadedAt: uploadedAt.toISOString()
        }
      });

      // 生成访问 URL
      const url = this.generatePublicUrl(id);

      return {
        id,
        url,
        filename,
        size,
        mimeType,
        uploadedAt,
        dimensions
      };
    } catch (error) {
      this.logger.error('Failed to upload file to OSS', error as Error);
      throw new Error(`Failed to upload file: ${(error as Error).message}`);
    }
  }

  async delete(id: string): Promise<void> {
    this.ensureInitialized();
    
    try {
      await this.ossClient.delete(id);
    } catch (error) {
      this.logger.error('Failed to delete file from OSS', error as Error);
      throw new Error(`Failed to delete file: ${(error as Error).message}`);
    }
  }

  async exists(id: string): Promise<boolean> {
    this.ensureInitialized();
    
    try {
      await this.ossClient.head(id);
      return true;
    } catch (error) {
      return false;
    }
  }

  async getInfo(id: string): Promise<IUploadResult> {
    this.ensureInitialized();
    
    try {
      const result = await this.ossClient.head(id);
      const meta = result.meta || {};
      
      return {
        id,
        url: this.generatePublicUrl(id),
        filename: meta.originalName || id,
        size: parseInt(result.res.headers['content-length'] || '0'),
        mimeType: result.res.headers['content-type'] || 'application/octet-stream',
        uploadedAt: meta.uploadedAt ? new Date(meta.uploadedAt) : new Date()
      };
    } catch (error) {
      this.logger.error('Failed to get file info from OSS', error as Error);
      throw new Error(`File not found: ${id}`);
    }
  }

  async destroy(): Promise<void> {
    this.ossClient = null;
    this._initialized = false;
  }

  /**
   * 动态加载 OSS SDK
   */
  private async loadOSSSDK(): Promise<any> {
    try {
      // 在 Node.js 环境中加载
      if (typeof window === 'undefined') {
        return require('ali-oss');
      }
      
      // 在浏览器环境中，需要通过 script 标签或 CDN 加载
      if (typeof (window as any).OSS !== 'undefined') {
        return (window as any).OSS;
      }
      
      throw new Error('OSS SDK not available in browser environment');
    } catch (error) {
      throw new Error('Failed to load OSS SDK');
    }
  }

  /**
   * 测试连接
   */
  private async testConnection(): Promise<void> {
    try {
      await this.ossClient.getBucketInfo();
    } catch (error) {
      throw new Error('Failed to connect to OSS bucket');
    }
  }

  /**
   * 生成公共访问 URL
   */
  private generatePublicUrl(id: string): string {
    return `${this.endpoint}/${id}`;
  }
}
